package com.htfyun.eink.pw.draw.pen;

import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.htfyun.eink.pw.draw.IPWDrawPath;
import com.htfyun.eink.pw.draw.cache.IPathCache;
import com.htfyun.eink.pw.draw.cache.PathCachePathInfo;
import com.htfyun.eink.pw.draw.pointer.PWPointer;
import com.htfyun.eink.pw.draw.pointer.PWPointerActionEnums;

import java.util.ArrayList;
import java.util.List;

public class PenShapeCircle extends PenShapeBase {

    public static final String PEN_ID = PenShapeCircle.class.getSimpleName();

    private final Path pathShape = new Path();
    private final Rect pathRect = new Rect();

    private final PWPointer pointerDown = new PWPointer();

    private final Paint paint = new Paint();

    private IPathCache pathCache;

    private final PathCachePathInfo pathInfo = new PathCachePathInfo();

    @NonNull
    @Override
    public Rect getDirty() {
        return pathRect;
    }

    @NonNull
    @Override
    public String getPenId() {
        return PEN_ID;
    }

    @Nullable
    @Override
    public IPathCache getPathCache() {
        if (pathCache == null) {
            pathCache = new PenShapeCircle.PathCacheImpl();
        }
        return pathCache;
    }

    @Override
    public PenDrawPointerResultEnums pointerDown(@NonNull IPWDrawPath draw, @NonNull PWPointer pointer) {
        pointerDown.configBy(pointer);

        pathShape.reset();
        pathInfo.reset();
        pathInfo.setEraser(false);
        return PenDrawPointerResultEnums.NONE;
    }

    @Override
    public PenDrawPointerResultEnums pointerMove(@NonNull IPWDrawPath draw, @NonNull PWPointer pointer) {
        floatPath.reset();
        //画圆点到 移动点的 直线
        floatPath.moveTo(pointerDown.x, pointerDown.y);
        floatPath.lineTo(pointer.x, pointer.y);

        float radius = (float) Math.hypot((pointer.x - pointerDown.x), (pointer.y - pointerDown.y));
        floatPath.addCircle(pointerDown.x, pointerDown.y, radius, Path.Direction.CCW);

        return PenDrawPointerResultEnums.INVALIDATE_VIEW_ALL;
    }

    @Override
    public PenDrawPointerResultEnums pointerUp(@NonNull IPWDrawPath draw, @NonNull PWPointer pointer) {
        floatPath.reset();

        float radius = (float) Math.hypot((pointer.x - pointerDown.x), (pointer.y - pointerDown.y));
        pathShape.addCircle(pointerDown.x, pointerDown.y, radius, Path.Direction.CCW);

        draw.getPaintConfig().configPaint(paint);
        draw.drawPath(pathShape, paint, pathRect);

        pathInfo.addRectForCheck(createRectsForCheckOfShape());
        pathInfo.addPath(pathShape);

        return PenDrawPointerResultEnums.INVALIDATE_VIEW_ALL;
    }

    @NonNull
    public List<Rect> createRectsForCheckOfShape() {
        List<Rect> rects = new ArrayList<>();
        final int degreeStep = 18;//能被360除尽的值

        //半径
        float r = pathRect.width() / 2.0f;
        float theD;
        for (int degree = 0; degree <= 360; ) {

            theD = (float) (degree * Math.PI / 180);
            float x0 = (float) (pointerDown.x + r * Math.cos(theD));
            float y0 = (float) (pointerDown.y + r * Math.sin(theD));

            degree += degreeStep;

            theD = (float) (degree * Math.PI / 180);
            float x1 = (float) (pointerDown.x + r * Math.cos(theD));
            float y1 = (float) (pointerDown.y + r * Math.sin(theD));

            int left = (int) Math.min(x0, x1);
            int top = (int) Math.min(y0, y1);
            int right = (int) Math.max(x0, x1);
            int bottom = (int) Math.max(y0, y1);
            Rect rect = new Rect(left, top, right, bottom);

            rects.add(rect);
        }
        return rects;
    }

    protected class PathCacheImpl implements IPathCache {

        @Override
        public long getEventTimeOfPointerDown() {
            return pointerDown.eventTimeCache;
        }

        @Override
        public boolean canCachePointerByAction(@NonNull PWPointerActionEnums actionEnums) {
            switch (actionEnums) {
                case DOWN:
                case UP:
                    return true;
                default:
                    break;
            }
            return false;
        }

        @NonNull
        @Override
        public String getPenId() {
            return PenShapeCircle.this.getPenId();
        }

        @NonNull
        @Override
        public PathCachePathInfo getCachePathInfo() {
            return pathInfo;
        }

    }
}
